﻿/*============================================================================
  File:    Program.cs

  Summary: Create an analysis services database from the data warehouse.

  Date:    February 2005
------------------------------------------------------------------------------
  This file is part of the Microsoft SQL Server Code Samples.

  Copyright (C) Microsoft Corporation.  All rights reserved.

  This source code is intended only as a supplement to Microsoft
  Development Tools and/or on-line documentation.  See these other
  materials for detailed information regarding Microsoft code samples.

  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
============================================================================*/

#region Using directives

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Text;
using System.Data;
using System.Data.OleDb;
using Microsoft.AnalysisServices;

#endregion

namespace Microsoft.Samples.SqlServer
{
    class Program
    {
        static private string datasourceName
            = Properties.Settings.Default.DWDatabaseName;

        static void Main()
        {
            using (Server svr = new Server())
            {
                svr.Connect(Properties.Settings.Default.ServerName);

                CreateAndProcessDatabase(svr);

                svr.Disconnect();
            }
        }

        static void CreateAndProcessDatabase(Server svr)
        {
            // Drop the AmoAdventureWorks database if it already exists
            Database db = svr.Databases.FindByName(
                Properties.Settings.Default.DatabaseName);
            if (db != null)
            {
                db.Drop();
            }

            // Create the AmoAdventureWorks database
            db = svr.Databases.Add(Properties.Settings.Default.DatabaseName);
            db.DataSourceImpersonationInfo
                = new ImpersonationInfo(ImpersonationMode.ImpersonateServiceAccount);
            db.Update();

            // Create the data source and data source view
            CreateDataSource(db);
            CreateDataSourceView(db);

            // Create the dimensions
            CreateDateDimension(db);
            CreateProductDimension(db);
            CreateCustomerDimension(db);
            CreateResellerDimension(db);
            CreateGeographyDimension(db);
            CreateCurrencyDimension(db);
            CreateInternetSalesOrderDetailsDimension(db);
            CreateResellerSalesOrderDetailsDimension(db);
            CreateSalesReasonDimension(db);

            // Create the cube
            CreateAdventureWorksCube(db);

            // Create the stored procedures
            CreateStoredProcedures(db);

            // Create the roles and permissions
            CreateRolesAndPermissions(db);

            // Start the default trace
            svr.SessionTrace.OnEvent
                += new TraceEventHandler(DefaultTrace_OnEvent);
            svr.SessionTrace.Stopped
                += new TraceStoppedEventHandler(DefaultTrace_Stopped);
            svr.SessionTrace.Start();

            // Process the database
            // The trace handlers will output all progress notifications 
            // to the console
            db.Process();

            // Stop the default trace
            svr.SessionTrace.Stop();
        }

        static void DefaultTrace_OnEvent(object sender, TraceEventArgs e)
        {
            Console.WriteLine("{0}", e.TextData);
        }

        static void DefaultTrace_Stopped(ITrace sender, TraceStoppedEventArgs e)
        {
            switch (e.StopCause)
            {
                case TraceStopCause.StoppedByUser:
                case TraceStopCause.Finished:
                    Console.WriteLine("Processing completed successfully");
                    break;

                case TraceStopCause.StoppedByException:
                    Console.WriteLine("Processing failed: {0}",
                        e.Exception.Message);
                    break;
            }
        }

        static void CreateDataSource(Database db)
        {
            // Create the data source
            DataSource ds = db.DataSources.Add(datasourceName);
            ds.ConnectionString = Properties.Settings.Default.AdventureWorksDW;

            // Send the data source definition to the server.
            ds.Update();
        }

        static void CreateDataSourceView(Database db)
        {
            // Create the data source view
            DataSourceView dsv = db.DataSourceViews.Add(datasourceName);
            dsv.DataSourceID = datasourceName;
            dsv.Schema = new DataSet();
            dsv.Schema.Locale = CultureInfo.CurrentCulture;

            // Open a connection to the data source
            OleDbConnection connection
                = new OleDbConnection(dsv.DataSource.ConnectionString);
            connection.Open();

            #region Create tables

            // Add the DimTime table
            AddTable(dsv, connection, "DimTime");
            AddComputedColumn(dsv, connection, "DimTime", "SimpleDate", "DATENAME(mm, FullDateAlternateKey) + ' ' + DATENAME(dd, FullDateAlternateKey) + ',' + ' ' + DATENAME(yy, FullDateAlternateKey)");
            AddComputedColumn(dsv, connection, "DimTime", "CalendarYearDesc", "'CY' + ' ' + CalendarYear");
            AddComputedColumn(dsv, connection, "DimTime", "CalendarSemesterDesc", "CASE WHEN CalendarSemester = 1 THEN 'H1'+' '+ 'CY' +' '+ CONVERT(CHAR (4), CalendarYear) ELSE 'H2'+' '+ 'CY' +' '+ CONVERT(CHAR (4), CalendarYear) END");
            AddComputedColumn(dsv, connection, "DimTime", "CalendarQuarterDesc", "'Q' + CONVERT(CHAR (1), CalendarQuarter) +' '+ 'CY' +' '+ CONVERT(CHAR (4), CalendarYear)");
            AddComputedColumn(dsv, connection, "DimTime", "MonthName", "EnglishMonthName+' '+ CONVERT(CHAR (4), CalendarYear)");
            AddComputedColumn(dsv, connection, "DimTime", "FiscalYearDesc", "'FY' + ' ' + FiscalYear");
            AddComputedColumn(dsv, connection, "DimTime", "FiscalSemesterDesc", "CASE WHEN FiscalSemester = 1 THEN 'H1'+' '+ 'FY' +' '+ CONVERT(CHAR (4), FiscalYear) ELSE 'H2'+' '+ 'FY' +' '+ CONVERT(CHAR (4), FiscalYear) END");
            AddComputedColumn(dsv, connection, "DimTime", "FiscalQuarterDesc", "'Q' + CONVERT(CHAR (1), FiscalQuarter) +' '+ 'FY' +' '+ CONVERT(CHAR (4), FiscalYear)");
            AddComputedColumn(dsv, connection, "DimTime", "FiscalMonthNumberOfYear", "CASE WHEN MonthNumberOfYear = '1'  THEN CONVERT(int,'7') WHEN MonthNumberOfYear = '2'  THEN CONVERT(int,'8') WHEN MonthNumberOfYear = '3'  THEN CONVERT(int,'9') WHEN MonthNumberOfYear = '4'  THEN CONVERT(int,'10') WHEN MonthNumberOfYear = '5'  THEN CONVERT(int,'11') WHEN MonthNumberOfYear = '6'  THEN CONVERT(int,'12') WHEN MonthNumberOfYear = '7'  THEN CONVERT(int,'1') WHEN MonthNumberOfYear = '8'  THEN CONVERT(int,'2') WHEN MonthNumberOfYear = '9'  THEN CONVERT(int,'3') WHEN MonthNumberOfYear = '10' THEN CONVERT(int,'4') WHEN MonthNumberOfYear = '11' THEN CONVERT(int,'5') WHEN MonthNumberOfYear = '12' THEN CONVERT(int,'6') END");

            // Add the DimGeography table
            AddTable(dsv, connection, "DimGeography");

            // Add the DimProductCategory table
            AddTable(dsv, connection, "DimProductCategory");

            // Add the DimProductSubcategory table
            AddTable(dsv, connection, "DimProductSubcategory");
            AddRelation(dsv, "DimProductSubcategory", "ProductCategoryKey", "DimProductCategory", "ProductCategoryKey");

            // Add the DimProduct table
            AddTable(dsv, connection, "DimProduct");
            AddComputedColumn(dsv, connection, "DimProduct", "ProductLineName", "CASE ProductLine WHEN 'M' THEN 'Mountain' WHEN 'R' THEN 'Road' WHEN 'S' THEN 'Accessory' WHEN 'T' THEN 'Touring' ELSE 'Components' END");
            AddRelation(dsv, "DimProduct", "ProductSubcategoryKey", "DimProductSubcategory", "ProductSubcategoryKey");

            // Add the DimCustomer table
            AddTable(dsv, connection, "DimCustomer");
            AddComputedColumn(dsv, connection, "DimCustomer", "FullName", "CASE WHEN MiddleName IS NULL THEN FirstName + ' ' + LastName ELSE FirstName + ' ' + MiddleName + ' ' + LastName END");
            AddComputedColumn(dsv, connection, "DimCustomer", "GenderDesc", "CASE WHEN Gender = 'M' THEN 'Male' ELSE 'Female' END");
            AddComputedColumn(dsv, connection, "DimCustomer", "MaritalStatusDesc", "CASE WHEN MaritalStatus = 'S' THEN 'Single' ELSE 'Married' END");
            AddRelation(dsv, "DimCustomer", "GeographyKey", "DimGeography", "GeographyKey");

            // Add the DimReseller table
            AddTable(dsv, connection, "DimReseller");
            AddComputedColumn(dsv, connection, "DimReseller", "OrderFrequencyDesc", "CASE WHEN OrderFrequency = 'A' THEN 'Annual' WHEN OrderFrequency = 'S' THEN 'Bi-Annual' ELSE 'Quarterly' END");
            AddComputedColumn(dsv, connection, "DimReseller", "OrderMonthDesc", "CASE WHEN OrderMonth = '1' THEN 'January' WHEN OrderMonth = '2' THEN 'February' WHEN OrderMonth = '3' THEN 'March' WHEN OrderMonth = '4' THEN 'April' WHEN OrderMonth = '5' THEN 'May' WHEN OrderMonth = '6' THEN 'June' WHEN OrderMonth = '7' THEN 'July' WHEN OrderMonth = '8' THEN 'August' WHEN OrderMonth = '9' THEN 'September' WHEN OrderMonth = '10' THEN 'October' WHEN OrderMonth = '11' THEN 'November' WHEN OrderMonth = '12' THEN 'December' ELSE 'Never Ordered' END");

            // Add the DimCurrency table
            AddTable(dsv, connection, "DimCurrency");

            // Add the DimSalesReason table
            AddTable(dsv, connection, "DimSalesReason");

            // Add the FactInternetSales table
            AddTable(dsv, connection, "FactInternetSales");
            AddRelation(dsv, "FactInternetSales", "ProductKey", "DimProduct", "ProductKey");
            AddRelation(dsv, "FactInternetSales", "CustomerKey", "DimCustomer", "CustomerKey");
            AddRelation(dsv, "FactInternetSales", "OrderDateKey", "DimTime", "TimeKey");
            AddRelation(dsv, "FactInternetSales", "ShipDateKey", "DimTime", "TimeKey");
            AddRelation(dsv, "FactInternetSales", "DueDateKey", "DimTime", "TimeKey");
            AddRelation(dsv, "FactInternetSales", "CurrencyKey", "DimCurrency", "CurrencyKey");

            // Add the FactResellerSales table
            AddTable(dsv, connection, "FactResellerSales");
            AddRelation(dsv, "FactResellerSales", "ProductKey", "DimProduct", "ProductKey");
            AddRelation(dsv, "FactResellerSales", "ResellerKey", "DimReseller", "ResellerKey");
            AddRelation(dsv, "FactResellerSales", "OrderDateKey", "DimTime", "TimeKey");
            AddRelation(dsv, "FactResellerSales", "ShipDateKey", "DimTime", "TimeKey");
            AddRelation(dsv, "FactResellerSales", "DueDateKey", "DimTime", "TimeKey");
            AddRelation(dsv, "FactResellerSales", "CurrencyKey", "DimCurrency", "CurrencyKey");

            // Add the FactInternetSalesReason table
            AddTable(dsv, connection, "FactInternetSalesReason");
            AddCompositeRelation(dsv, "FactInternetSalesReason", "FactInternetSales", "SalesOrderNumber", "SalesOrderLineNumber");

            // Add the FactCurrencyRate table
            AddTable(dsv, connection, "FactCurrencyRate");
            AddRelation(dsv, "FactCurrencyRate", "CurrencyKey", "DimCurrency", "CurrencyKey");
            AddRelation(dsv, "FactCurrencyRate", "TimeKey", "DimTime", "TimeKey");

            #endregion

            // Send the data source view definition to the server
            dsv.Update();
        }

        static void AddTable(DataSourceView dsv, OleDbConnection connection, String tableName)
        {
            OleDbDataAdapter adapter = new OleDbDataAdapter(
                "SELECT * FROM [dbo].[" + tableName + "] WHERE 1=0",
                connection);
            DataTable[] dataTables = adapter.FillSchema(dsv.Schema,
                SchemaType.Mapped, tableName);
            DataTable dataTable = dataTables[0];

            dataTable.ExtendedProperties.Add("TableType", "Table");
            dataTable.ExtendedProperties.Add("DbSchemaName", "dbo");
            dataTable.ExtendedProperties.Add("DbTableName", tableName);
            dataTable.ExtendedProperties.Add("FriendlyName", tableName);
        }

        static void AddComputedColumn(DataSourceView dsv, OleDbConnection connection, String tableName, String computedColumnName, String expression)
        {
            DataSet tmpDataSet = new DataSet();
            tmpDataSet.Locale = CultureInfo.CurrentCulture;
            OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT ("
                + expression + ") AS [" + computedColumnName + "] FROM [dbo].["
                + tableName + "] WHERE 1=0", connection);
            DataTable[] dataTables = adapter.FillSchema(tmpDataSet,
                SchemaType.Mapped, tableName);
            DataTable dataTable = dataTables[0];
            DataColumn dataColumn = dataTable.Columns[computedColumnName];

            dataTable.Constraints.Clear();
            dataTable.Columns.Remove(dataColumn);

            dataColumn.ExtendedProperties.Add("DbColumnName", computedColumnName);
            dataColumn.ExtendedProperties.Add("ComputedColumnExpression",
                expression);
            dataColumn.ExtendedProperties.Add("IsLogical", "True");

            dsv.Schema.Tables[tableName].Columns.Add(dataColumn);
        }

        static void AddRelation(DataSourceView dsv, String fkTableName, String fkColumnName, String pkTableName, String pkColumnName)
        {
            DataColumn fkColumn
                = dsv.Schema.Tables[fkTableName].Columns[fkColumnName];
            DataColumn pkColumn
                = dsv.Schema.Tables[pkTableName].Columns[pkColumnName];
            dsv.Schema.Relations.Add("FK_" + fkTableName + "_"
                + fkColumnName, pkColumn, fkColumn, true);
        }

        static void AddCompositeRelation(DataSourceView dsv, String fkTableName, String pkTableName, String columnName1, String columnName2)
        {
            DataColumn[] fkColumns = new DataColumn[2];
            fkColumns[0] = dsv.Schema.Tables[fkTableName].Columns[columnName1];
            fkColumns[1] = dsv.Schema.Tables[fkTableName].Columns[columnName2];

            DataColumn[] pkColumns = new DataColumn[2];
            pkColumns[0] = dsv.Schema.Tables[pkTableName].Columns[columnName1];
            pkColumns[1] = dsv.Schema.Tables[pkTableName].Columns[columnName2];

            dsv.Schema.Relations.Add("FK_" + fkTableName + "_" + columnName1
                + "_" + columnName2, pkColumns, fkColumns, true);
        }

        static DataItem CreateDataItem(DataSourceView dsv, string tableName, string columnName)
        {
            DataTable dataTable = ((DataSourceView)dsv).Schema.Tables[tableName];
            DataColumn dataColumn = dataTable.Columns[columnName];
            return new DataItem(tableName, columnName,
                OleDbTypeConverter.GetRestrictedOleDbType(dataColumn.DataType));
        }

        static void CreateDateDimension(Database db)
        {
            // Create the Date dimension
            Dimension dim = db.Dimensions.Add("Date");
            dim.Type = DimensionType.Time;
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.AttributeAllMemberName = "All Periods";
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Molap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Date");
            attr.Usage = AttributeUsage.Key;
            attr.Type = AttributeType.Date;
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "TimeKey"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "SimpleDate");

            attr = dim.Attributes.Add("Calendar Year");
            attr.Type = AttributeType.Years;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarYear"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarYearDesc");

            attr = dim.Attributes.Add("Calendar Semester");
            attr.Type = AttributeType.HalfYears;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarYear"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarSemester"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarSemesterDesc");
            attr.AttributeRelationships.Add(new AttributeRelationship("Calendar Year"));

            attr = dim.Attributes.Add("Calendar Quarter");
            attr.Type = AttributeType.Quarters;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarYear"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarQuarter"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarQuarterDesc");
            attr.AttributeRelationships.Add(new AttributeRelationship("Calendar Semester"));
            attr.AttributeRelationships.Add(new AttributeRelationship("Fiscal Quarter"));

            attr = dim.Attributes.Add("Calendar Month Number");
            attr.Type = AttributeType.MonthOfYear;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "MonthNumberOfYear"));

            attr = dim.Attributes.Add("Calendar Month Name");
            attr.Type = AttributeType.Months;
            attr.OrderBy = OrderBy.AttributeKey;
            attr.OrderByAttributeID = "Calendar Month Number";
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarYear"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "EnglishMonthName"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "MonthName");
            attr.AttributeRelationships.Add(new AttributeRelationship("Calendar Month Number"));
            attr.AttributeRelationships.Add(new AttributeRelationship("Calendar Quarter"));

            attr = dim.Attributes.Add("Fiscal Year");
            attr.Type = AttributeType.FiscalYears;
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalYear"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalYearDesc");

            attr = dim.Attributes.Add("Fiscal Semester");
            attr.Type = AttributeType.FiscalHalfYears;
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalYear"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalSemester"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalSemesterDesc");

            attr = dim.Attributes.Add("Fiscal Quarter");
            attr.Type = AttributeType.FiscalQuarters;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalYear"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalQuarter"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalQuarterDesc");
            attr.AttributeRelationships.Add(new AttributeRelationship("Fiscal Semester"));

            attr = dim.Attributes.Add("Fiscal Month Number");
            attr.Type = AttributeType.FiscalMonthOfYear;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "FiscalMonthNumberOfYear"));

            attr = dim.Attributes.Add("Fiscal Month Name");
            attr.Type = AttributeType.FiscalMonths;
            attr.OrderBy = OrderBy.AttributeKey;
            attr.OrderByAttributeID = "Fiscal Month Number";
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "CalendarYear"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimTime", "EnglishMonthName"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimTime", "MonthName");
            attr.AttributeRelationships.Add(new AttributeRelationship("Fiscal Month Number"));
            attr.AttributeRelationships.Add(new AttributeRelationship("Fiscal Quarter"));

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Calendar Time");
            hier.AllMemberName = "All Periods";
            hier.Levels.Add("Calendar Year").SourceAttributeID = "Calendar Year"; //TODO: Get ID from attribute object
            hier.Levels.Add("Calendar Semester").SourceAttributeID = "Calendar Semester";
            hier.Levels.Add("Calendar Quarter").SourceAttributeID = "Calendar Quarter";
            hier.Levels.Add("Month").SourceAttributeID = "Calendar Month Name";
            hier.Levels.Add("Date").SourceAttributeID = "Date";

            hier = dim.Hierarchies.Add("Fiscal Time");
            hier.AllMemberName = "All Periods";
            hier.Levels.Add("Fiscal Year").SourceAttributeID = "Fiscal Year";
            hier.Levels.Add("Fiscal Semester").SourceAttributeID = "Fiscal Semester";
            hier.Levels.Add("Fiscal Quarter").SourceAttributeID = "Fiscal Quarter";
            hier.Levels.Add("Month").SourceAttributeID = "Fiscal Month Name";
            hier.Levels.Add("Date").SourceAttributeID = "Date";

            #endregion

            dim.Update();
        }

        static void CreateProductDimension(Database db)
        {
            // Create the Product dimension
            Dimension dim = db.Dimensions.Add("Product");
            dim.Type = DimensionType.Products;
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.AttributeAllMemberName = "All Products";
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Molap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Product Name");
            attr.Usage = AttributeUsage.Key;
            attr.Type = AttributeType.Product;
            attr.OrderBy = OrderBy.Name;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProduct", "ProductKey"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimProduct", "EnglishProductName");
            //TODO: translations

            attr = dim.Attributes.Add("Product Line");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProduct", "ProductLine"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimProduct", "ProductLineName");

            attr = dim.Attributes.Add("Model Name");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProduct", "ModelName"));
            attr.AttributeRelationships.Add(new AttributeRelationship("Product Line"));
            attr.AttributeRelationships.Add(new AttributeRelationship("Subcategory"));

            attr = dim.Attributes.Add("Subcategory");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProductSubcategory", "ProductSubcategoryKey"));
            attr.KeyColumns[0].NullProcessing = NullProcessing.UnknownMember;
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimProductSubcategory", "EnglishProductSubcategoryName");
            attr.AttributeRelationships.Add(new AttributeRelationship("Category"));

            attr = dim.Attributes.Add("Category");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProductCategory", "ProductCategoryKey"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimProductCategory", "EnglishProductCategoryName");

            attr = dim.Attributes.Add("List Price");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProduct", "ListPrice"));
            attr.AttributeHierarchyEnabled = false;

            attr = dim.Attributes.Add("Size");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProduct", "Size"));
            attr.AttributeHierarchyEnabled = false;

            attr = dim.Attributes.Add("Weight");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimProduct", "Weight"));
            attr.AttributeHierarchyEnabled = false;

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Product Model Categories");
            hier.AllMemberName = "All Products";
            hier.Levels.Add("Category").SourceAttributeID = "Category";
            hier.Levels.Add("Subcategory").SourceAttributeID = "Subcategory";
            hier.Levels.Add("Model Name").SourceAttributeID = "Model Name";

            hier = dim.Hierarchies.Add("Product Categories");
            hier.AllMemberName = "All Products";
            hier.Levels.Add("Category").SourceAttributeID = "Category";
            hier.Levels.Add("Subcategory").SourceAttributeID = "Subcategory";
            hier.Levels.Add("Model Name").SourceAttributeID = "Product Name";

            hier = dim.Hierarchies.Add("Product Model Lines");
            hier.AllMemberName = "All Products";
            hier.Levels.Add("Subcategory").SourceAttributeID = "Product Line";
            hier.Levels.Add("Model Name").SourceAttributeID = "Model Name";

            #endregion

            dim.Update();
        }

        static void CreateCustomerDimension(Database db)
        {
            // Create the Customer dimension
            Dimension dim = db.Dimensions.Add("Customer");
            dim.Type = DimensionType.Customers;
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.AttributeAllMemberName = "All Customers";
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Molap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Full Name");
            attr.Usage = AttributeUsage.Key;
            attr.Type = AttributeType.Customers;
            attr.OrderBy = OrderBy.Name;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCustomer", "CustomerKey"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimCustomer", "FullName");

            attr = dim.Attributes.Add("Country-Region");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "EnglishCountryRegionName"));

            attr = dim.Attributes.Add("State-Province");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "CountryRegionCode"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "StateProvinceCode"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimGeography", "StateProvinceName");
            attr.AttributeRelationships.Add(new AttributeRelationship("Country-Region"));

            attr = dim.Attributes.Add("City");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "StateProvinceCode"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "City"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimGeography", "City");
            attr.AttributeRelationships.Add(new AttributeRelationship("State-Province"));

            attr = dim.Attributes.Add("Postal Code");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "City"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "PostalCode"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimGeography", "PostalCode");
            attr.AttributeRelationships.Add(new AttributeRelationship("City"));

            attr = dim.Attributes.Add("Education");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCustomer", "EnglishEducation"));

            attr = dim.Attributes.Add("Email Address");
            attr.AttributeHierarchyEnabled = false;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCustomer", "EmailAddress"));

            attr = dim.Attributes.Add("Gender");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCustomer", "GenderDesc"));

            attr = dim.Attributes.Add("Marital Status");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCustomer", "MaritalStatusDesc"));

            attr = dim.Attributes.Add("Occupation");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCustomer", "EnglishOccupation"));

            attr = dim.Attributes.Add("Phone");
            attr.AttributeHierarchyEnabled = false;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCustomer", "Phone"));

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Customer Geography");
            hier.AllMemberName = "All Customers";
            hier.Levels.Add("Country-Region").SourceAttributeID = "Country-Region";
            hier.Levels.Add("State-Province").SourceAttributeID = "State-Province";
            hier.Levels.Add("City").SourceAttributeID = "City";
            hier.Levels.Add("Postal Code").SourceAttributeID = "Postal Code";
            hier.Levels.Add("Full Name").SourceAttributeID = "Full Name";

            #endregion

            dim.Update();
        }

        static void CreateResellerDimension(Database db)
        {
            // Create the Reseller dimension
            Dimension dim = db.Dimensions.Add("Reseller");
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.AttributeAllMemberName = "All Resellers";
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Molap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Reseller");
            attr.Usage = AttributeUsage.Key;
            attr.OrderBy = OrderBy.Name;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "ResellerKey"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimReseller", "ResellerName");

            attr = dim.Attributes.Add("Business Type");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "BusinessType"));

            attr = dim.Attributes.Add("Bank Name");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "BankName"));

            attr = dim.Attributes.Add("Order Frequency");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "OrderFrequency"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimReseller", "OrderFrequencyDesc");

            attr = dim.Attributes.Add("Order Month");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "OrderMonth"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimReseller", "OrderMonthDesc");

            attr = dim.Attributes.Add("Geography Key");
            attr.AttributeHierarchyVisible = false;
            attr.AttributeHierarchyOptimizedState = OptimizationType.NotOptimized;
            attr.AttributeHierarchyOrdered = false;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "GeographyKey"));

            attr = dim.Attributes.Add("Address");
            attr.AttributeHierarchyEnabled = false;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "AddressLine1"));

            attr = dim.Attributes.Add("Number of Employees");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "NumberEmployees"));

            attr = dim.Attributes.Add("Phone");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "Phone"));

            attr = dim.Attributes.Add("Product Line");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimReseller", "ProductLine"));

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Reseller Type");
            hier.AllMemberName = "All Resellers";
            hier.Levels.Add("Business Type").SourceAttributeID = "Business Type";
            hier.Levels.Add("Reseller").SourceAttributeID = "Reseller";

            hier = dim.Hierarchies.Add("Reseller Bank");
            hier.AllMemberName = "All Resellers";
            hier.Levels.Add("Bank Name").SourceAttributeID = "Bank Name";
            hier.Levels.Add("Reseller").SourceAttributeID = "Reseller";

            hier = dim.Hierarchies.Add("Reseller Order Frequency");
            hier.AllMemberName = "All Resellers";
            hier.Levels.Add("Order Frequency").SourceAttributeID = "Order Frequency";
            hier.Levels.Add("Reseller").SourceAttributeID = "Reseller";

            hier = dim.Hierarchies.Add("Reseller Order Month");
            hier.AllMemberName = "All Resellers";
            hier.Levels.Add("Order Month").SourceAttributeID = "Order Month";
            hier.Levels.Add("Reseller").SourceAttributeID = "Reseller";

            #endregion

            dim.Update();
        }

        static void CreateGeographyDimension(Database db)
        {
            // Create the Geography dimension
            Dimension dim = db.Dimensions.Add("Geography");
            dim.Type = DimensionType.Geography;
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.AttributeAllMemberName = "All Geographies";
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Molap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Geography Key");
            attr.Usage = AttributeUsage.Key;
            attr.OrderBy = OrderBy.Name;
            attr.AttributeHierarchyVisible = false;
            attr.AttributeHierarchyOptimizedState = OptimizationType.NotOptimized;
            attr.AttributeHierarchyOrdered = false;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "GeographyKey"));

            attr = dim.Attributes.Add("Country-Region");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "EnglishCountryRegionName"));

            attr = dim.Attributes.Add("State-Province");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "CountryRegionCode"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "StateProvinceCode"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimGeography", "StateProvinceName");
            attr.AttributeRelationships.Add(new AttributeRelationship("Country-Region"));

            attr = dim.Attributes.Add("City");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "StateProvinceCode"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "City"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimGeography", "City");
            attr.AttributeRelationships.Add(new AttributeRelationship("State-Province"));

            attr = dim.Attributes.Add("Postal Code");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "City"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimGeography", "PostalCode"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimGeography", "PostalCode");
            attr.AttributeRelationships.Add(new AttributeRelationship("City"));

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Geography");
            hier.AllMemberName = "All Geographies";
            hier.Levels.Add("Country-Region").SourceAttributeID = "Country-Region";
            hier.Levels.Add("State-Province").SourceAttributeID = "State-Province";
            hier.Levels.Add("City").SourceAttributeID = "City";
            hier.Levels.Add("Postal Code").SourceAttributeID = "Postal Code";

            #endregion

            dim.Update();
        }

        static void CreateCurrencyDimension(Database db)
        {
            // Create the Currency dimension
            Dimension dim = db.Dimensions.Add("Currency");
            dim.Type = DimensionType.Currency;
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.AttributeAllMemberName = "All Currencies";
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Molap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Currency");
            attr.Usage = AttributeUsage.Key;
            attr.Type = AttributeType.CurrencyName;
            attr.OrderBy = OrderBy.Name;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCurrency", "CurrencyKey"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimCurrency", "CurrencyName");

            attr = dim.Attributes.Add("Currency Code");
            attr.AttributeHierarchyEnabled = false;
            attr.Type = AttributeType.CurrencyIsoCode;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimCurrency", "CurrencyAlternateKey"));

            #endregion

            #region Create hierarchies

            #endregion

            dim.Update();
        }

        static void CreateInternetSalesOrderDetailsDimension(Database db)
        {
            // Create the Internet Sales Order Details dimension
            Dimension dim = db.Dimensions.Add("Internet Sales Order Details");
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Rolap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Sales Order Key");
            attr.Usage = AttributeUsage.Key;
            attr.OrderBy = OrderBy.Name;
            attr.AttributeHierarchyVisible = false;
            attr.AttributeHierarchyOptimizedState = OptimizationType.NotOptimized;
            attr.AttributeHierarchyOrdered = false;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesOrderNumber"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesOrderLineNumber"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesOrderNumber");

            attr = dim.Attributes.Add("Sales Order Number");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesOrderNumber"));

            attr = dim.Attributes.Add("Sales Order Line");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesOrderLineNumber"));

            attr = dim.Attributes.Add("Carrier Tracking Number");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "CarrierTrackingNumber"));

            attr = dim.Attributes.Add("Customer PO Number");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "CustomerPONumber"));

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Internet Sales Orders");
            hier.Levels.Add("Order Number").SourceAttributeID = "Sales Order Number";
            hier.Levels.Add("Order Line").SourceAttributeID = "Sales Order Line";

            #endregion

            dim.Update();
        }

        static void CreateResellerSalesOrderDetailsDimension(Database db)
        {
            // Create the Reseller Sales Order Details dimension
            Dimension dim = db.Dimensions.Add("Reseller Sales Order Details");
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Rolap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Sales Order Key");
            attr.Usage = AttributeUsage.Key;
            attr.OrderBy = OrderBy.Name;
            attr.AttributeHierarchyVisible = false;
            attr.AttributeHierarchyOptimizedState = OptimizationType.NotOptimized;
            attr.AttributeHierarchyOrdered = false;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "SalesOrderNumber"));
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "SalesOrderLineNumber"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "SalesOrderNumber");

            attr = dim.Attributes.Add("Sales Order Number");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "SalesOrderNumber"));

            attr = dim.Attributes.Add("Sales Order Line");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "SalesOrderLineNumber"));

            attr = dim.Attributes.Add("Carrier Tracking Number");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "CarrierTrackingNumber"));

            attr = dim.Attributes.Add("Customer PO Number");
            attr.OrderBy = OrderBy.Key;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "CustomerPONumber"));

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Reseller Sales Orders");
            hier.Levels.Add("Order Number").SourceAttributeID = "Sales Order Number";
            hier.Levels.Add("Order Line").SourceAttributeID = "Sales Order Line";

            #endregion

            dim.Update();
        }

        static void CreateSalesReasonDimension(Database db)
        {
            // Create the Sales Reason dimension
            Dimension dim = db.Dimensions.Add("Sales Reason");
            dim.UnknownMember = UnknownMemberBehavior.Hidden;
            dim.AttributeAllMemberName = "All Sales Reasons";
            dim.Source = new DataSourceViewBinding(datasourceName);
            dim.StorageMode = DimensionStorageMode.Molap;

            #region Create attributes

            DimensionAttribute attr;

            attr = dim.Attributes.Add("Sales Reason");
            attr.Usage = AttributeUsage.Key;
            attr.Type = AttributeType.CurrencyName;
            attr.OrderBy = OrderBy.Name;
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimSalesReason", "SalesReasonKey"));
            attr.NameColumn = CreateDataItem(db.DataSourceViews[0], "DimSalesReason", "SalesReasonName");

            attr = dim.Attributes.Add("Sales Reason Type");
            attr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "DimSalesReason", "SalesReasonReasonType"));

            #endregion

            #region Create hierarchies

            Hierarchy hier;

            hier = dim.Hierarchies.Add("Sales Reasons");
            hier.AllMemberName = "All Sales Reasons";
            hier.Levels.Add("Sales Reason Type").SourceAttributeID = "Sales Reason Type";
            hier.Levels.Add("Sales Reason").SourceAttributeID = "Sales Reason";

            #endregion

            dim.Update();
        }

        static void CreateAdventureWorksCube(Database db)
        {
            // Create the Adventure Works cube
            Cube cube = db.Cubes.Add("Adventure Works");
            cube.DefaultMeasure = "[Reseller Sales Amount]";
            cube.Source = new DataSourceViewBinding(datasourceName);
            cube.StorageMode = StorageMode.Molap;

            #region Create cube dimensions

            Dimension dim;

            dim = db.Dimensions.GetByName("Date");
            cube.Dimensions.Add(dim.ID, "Date", "Order Date Key - Dim Time");
            cube.Dimensions.Add(dim.ID, "Ship Date",
                "Ship Date Key - Dim Time");
            cube.Dimensions.Add(dim.ID, "Delivery Date",
                "Delivery Date Key - Dim Time");

            dim = db.Dimensions.GetByName("Customer");
            cube.Dimensions.Add(dim.ID);

            dim = db.Dimensions.GetByName("Reseller");
            cube.Dimensions.Add(dim.ID);

            dim = db.Dimensions.GetByName("Geography");
            cube.Dimensions.Add(dim.ID, "Reseller Geography", dim.ID);

            dim = db.Dimensions.GetByName("Product");
            cube.Dimensions.Add(dim.ID);

            dim = db.Dimensions.GetByName("Currency");
            cube.Dimensions.Add(dim.ID, "Source Currency", dim.ID);

            dim = db.Dimensions.GetByName("Sales Reason");
            cube.Dimensions.Add(dim.ID);

            dim = db.Dimensions.GetByName("Internet Sales Order Details");
            cube.Dimensions.Add(dim.ID);

            dim = db.Dimensions.GetByName("Reseller Sales Order Details");
            cube.Dimensions.Add(dim.ID);

            #endregion

            #region Create measure groups

            CreateSalesReasonsMeasureGroup(cube);
            CreateInternetSalesMeasureGroup(cube);
            CreateResellerSalesMeasureGroup(cube);
            CreateCustomersMeasureGroup(cube);
            CreateCurrencyRatesMeasureGroup(cube);

            #endregion

            cube.Update(UpdateOptions.ExpandFull);
        }

        static void CreateSalesReasonsMeasureGroup(Cube cube)
        {
            // Create the Sales Reasons measure group
            Database db = cube.Parent;
            MeasureGroup mg = cube.MeasureGroups.Add("Sales Reasons");
            mg.StorageMode = StorageMode.Molap;
            mg.ProcessingMode = ProcessingMode.LazyAggregations;

            #region Create measures

            Measure meas;

            meas = mg.Measures.Add("Sales Reason Count");
            meas.AggregateFunction = AggregationFunction.Count;
            meas.FormatString = "#";
            meas.Visible = false;
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSalesReason", "SalesOrderLineNumber");

            #endregion

            #region Create measure group dimensions

            CubeDimension cubeDim;
            RegularMeasureGroupDimension regMgDim;
            MeasureGroupAttribute mgAttr;

            cubeDim = cube.Dimensions.GetByName("Sales Reason");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Sales Reason").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSalesReason", "SalesReasonKey"));

            cubeDim = cube.Dimensions.GetByName("Internet Sales Order Details");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Sales Order Key").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSalesReason", "SalesOrderNumber"));
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSalesReason", "SalesOrderLineNumber"));

            #endregion

            #region Create partitions

            Partition part;

            part = mg.Partitions.Add("Fact_Internet_Sales_Reason");
            part.StorageMode = StorageMode.Molap;
            part.Source = new TableBinding(db.DataSources[0].ID, "dbo", "FactInternetSalesReason");

            #endregion
        }

        static void CreateInternetSalesMeasureGroup(Cube cube)
        {
            // Create the Internet Sales measure group
            Database db = cube.Parent;
            MeasureGroup mg = cube.MeasureGroups.Add("Internet Sales");
            mg.StorageMode = StorageMode.Molap;
            mg.ProcessingMode = ProcessingMode.LazyAggregations;
            mg.Type = MeasureGroupType.Sales;

            #region Create measures

            Measure meas;

            meas = mg.Measures.Add("Internet Sales Amount");
            meas.AggregateFunction = AggregationFunction.Sum;
            //meas.MeasureExpression = "[Internet Sales Amount] * [Average Rate]";
            meas.FormatString = "Currency";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesAmount");

            meas = mg.Measures.Add("Internet Order Quantity");
            meas.AggregateFunction = AggregationFunction.Sum;
            meas.FormatString = "#,#";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "OrderQuantity");

            meas = mg.Measures.Add("Internet Unit Price");
            meas.AggregateFunction = AggregationFunction.Sum;
            meas.FormatString = "Currency";
            meas.Visible = false;
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "UnitPrice");

            meas = mg.Measures.Add("Internet Total Product Cost");
            meas.AggregateFunction = AggregationFunction.Sum;
            //meas.MeasureExpression = "[Internet Total Product Cost] * [Average Rate]";
            meas.FormatString = "Currency";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "TotalProductCost");

            meas = mg.Measures.Add("Internet Order Count");
            meas.AggregateFunction = AggregationFunction.Count;
            meas.FormatString = "#,#";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "ProductKey");

            #endregion

            #region Create measure group dimensions

            CubeDimension cubeDim;
            RegularMeasureGroupDimension regMgDim;
            ManyToManyMeasureGroupDimension mmMgDim;
            MeasureGroupAttribute mgAttr;

            cubeDim = cube.Dimensions.GetByName("Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "OrderDateKey"));

            cubeDim = cube.Dimensions.GetByName("Ship Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "ShipDateKey"));

            cubeDim = cube.Dimensions.GetByName("Delivery Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "DueDateKey"));

            cubeDim = cube.Dimensions.GetByName("Customer");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Full Name").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "CustomerKey"));

            cubeDim = cube.Dimensions.GetByName("Product");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Product Name").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "ProductKey"));

            cubeDim = cube.Dimensions.GetByName("Source Currency");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Currency").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "CurrencyKey"));

            cubeDim = cube.Dimensions.GetByName("Sales Reason");
            mmMgDim = new ManyToManyMeasureGroupDimension();
            mmMgDim.CubeDimensionID = cubeDim.ID;
            mmMgDim.MeasureGroupID = cube.MeasureGroups.GetByName("Sales Reasons").ID;
            mg.Dimensions.Add(mmMgDim);

            cubeDim = cube.Dimensions.GetByName("Internet Sales Order Details");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Sales Order Key").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesOrderNumber"));
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "SalesOrderLineNumber"));

            #endregion

            #region Create partitions

            Partition part;

            part = mg.Partitions.Add("Internet_Sales_184");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey <= '184'");
            part.Annotations.Add("LastOrderDateKey", "184");

            part = mg.Partitions.Add("Internet_Sales_549");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey > '184' AND OrderDateKey <= '549'");
            part.Annotations.Add("LastOrderDateKey", "549");

            part = mg.Partitions.Add("Internet_Sales_914");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey > '549' AND OrderDateKey <= '914'");
            part.Annotations.Add("LastOrderDateKey", "914");

            #endregion
        }

        static void CreateResellerSalesMeasureGroup(Cube cube)
        {
            // Create the Reseller Sales measure group
            Database db = cube.Parent;
            MeasureGroup mg = cube.MeasureGroups.Add("Reseller Sales");
            mg.StorageMode = StorageMode.Molap;
            mg.ProcessingMode = ProcessingMode.LazyAggregations;
            mg.Type = MeasureGroupType.Sales;

            #region Create measures

            Measure meas;

            meas = mg.Measures.Add("Reseller Sales Amount");
            meas.AggregateFunction = AggregationFunction.Sum;
            //meas.MeasureExpression = "[Reseller Sales Amount] * [Average Rate]";
            meas.FormatString = "Currency";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "SalesAmount");

            meas = mg.Measures.Add("Reseller Order Quantity");
            meas.AggregateFunction = AggregationFunction.Sum;
            meas.FormatString = "#,#";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "OrderQuantity");

            meas = mg.Measures.Add("Reseller Unit Price");
            meas.AggregateFunction = AggregationFunction.Sum;
            meas.FormatString = "Currency";
            meas.Visible = false;
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "UnitPrice");

            meas = mg.Measures.Add("Reseller Total Product Cost");
            meas.AggregateFunction = AggregationFunction.Sum;
            //meas.MeasureExpression = "[Reseller Total Product Cost] * [Average Rate]";
            meas.FormatString = "Currency";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "TotalProductCost");

            meas = mg.Measures.Add("Reseller Order Count");
            meas.AggregateFunction = AggregationFunction.Count;
            meas.FormatString = "#,#";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "ProductKey");

            #endregion

            #region Create measure group dimensions

            CubeDimension cubeDim;
            CubeDimension intermediateCubeDim;
            RegularMeasureGroupDimension regMgDim;
            ReferenceMeasureGroupDimension refMgDim;
            MeasureGroupAttribute mgAttr;

            cubeDim = cube.Dimensions.GetByName("Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "OrderDateKey"));

            cubeDim = cube.Dimensions.GetByName("Ship Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "ShipDateKey"));

            cubeDim = cube.Dimensions.GetByName("Delivery Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "DueDateKey"));

            cubeDim = cube.Dimensions.GetByName("Reseller");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Reseller").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactResellerSales", "ResellerKey"));

            cubeDim = cube.Dimensions.GetByName("Reseller Geography");
            intermediateCubeDim = cube.Dimensions.GetByName("Reseller");
            refMgDim = new ReferenceMeasureGroupDimension();
            refMgDim.CubeDimensionID = cubeDim.ID;
            mgAttr = refMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Geography Key").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            refMgDim.IntermediateCubeDimensionID = intermediateCubeDim.ID;
            refMgDim.IntermediateGranularityAttributeID
                = intermediateCubeDim.Dimension.Attributes.GetByName("Geography Key").ID;
            mg.Dimensions.Add(refMgDim);

            cubeDim = cube.Dimensions.GetByName("Product");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Product Name").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactResellerSales", "ProductKey"));

            cubeDim = cube.Dimensions.GetByName("Source Currency");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Currency").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactResellerSales", "CurrencyKey"));

            cubeDim = cube.Dimensions.GetByName("Reseller Sales Order Details");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Sales Order Key").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactResellerSales", "SalesOrderNumber"));
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactResellerSales", "SalesOrderLineNumber"));

            #endregion

            #region Create partitions

            Partition part;

            part = mg.Partitions.Add("Reseller_Sales_184");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactResellerSales] WHERE OrderDateKey <= '184'");
            part.Annotations.Add("LastOrderDateKey", "184");

            part = mg.Partitions.Add("Reseller_Sales_549");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactResellerSales] WHERE OrderDateKey > '184' AND OrderDateKey <= '549'");
            part.Annotations.Add("LastOrderDateKey", "549");

            part = mg.Partitions.Add("Reseller_Sales_914");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactResellerSales] WHERE OrderDateKey > '549' AND OrderDateKey <= '914'");
            part.Annotations.Add("LastOrderDateKey", "914");

            #endregion
        }

        static void CreateCustomersMeasureGroup(Cube cube)
        {
            // Create the Customers measure group
            Database db = cube.Parent;
            MeasureGroup mg = cube.MeasureGroups.Add("Customers");
            mg.StorageMode = StorageMode.Molap;
            mg.ProcessingMode = ProcessingMode.LazyAggregations;

            #region Create measures

            Measure meas;

            meas = mg.Measures.Add("Customer Count");
            meas.AggregateFunction = AggregationFunction.DistinctCount;
            meas.FormatString = "#,#";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactInternetSales", "CustomerKey");

            #endregion

            #region Create measure group dimensions

            CubeDimension cubeDim;
            RegularMeasureGroupDimension regMgDim;
            ManyToManyMeasureGroupDimension mmMgDim;
            MeasureGroupAttribute mgAttr;

            cubeDim = cube.Dimensions.GetByName("Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactInternetSales", "OrderDateKey"));

            cubeDim = cube.Dimensions.GetByName("Ship Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactInternetSales", "ShipDateKey"));

            cubeDim = cube.Dimensions.GetByName("Delivery Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactInternetSales", "DueDateKey"));

            cubeDim = cube.Dimensions.GetByName("Customer");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Full Name").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactInternetSales", "CustomerKey"));

            cubeDim = cube.Dimensions.GetByName("Product");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Product Name").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactInternetSales", "ProductKey"));

            cubeDim = cube.Dimensions.GetByName("Sales Reason");
            mmMgDim = new ManyToManyMeasureGroupDimension();
            mmMgDim.CubeDimensionID = cubeDim.ID;
            mmMgDim.MeasureGroupID
                = cube.MeasureGroups.GetByName("Sales Reasons").ID;
            mg.Dimensions.Add(mmMgDim);

            cubeDim = cube.Dimensions.GetByName("Internet Sales Order Details");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(
                cubeDim.Dimension.Attributes.GetByName("Sales Order Key").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactInternetSales", "SalesOrderNumber"));
            mgAttr.KeyColumns.Add(CreateDataItem(
                db.DataSourceViews[0], "FactInternetSales", "SalesOrderLineNumber"));

            #endregion

            #region Create partitions

            Partition part;

            part = mg.Partitions.Add("Customers_184");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey <= '184'");
            part.Annotations.Add("LastOrderDateKey", "184");

            part = mg.Partitions.Add("Customers_549");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey > '184' AND OrderDateKey <= '549'");
            part.Annotations.Add("LastOrderDateKey", "549");

            part = mg.Partitions.Add("Customers_914");
            part.StorageMode = StorageMode.Molap;
            part.Source = new QueryBinding(db.DataSources[0].ID, "SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey > '549' AND OrderDateKey <= '914'");
            part.Annotations.Add("LastOrderDateKey", "914");

            #endregion
        }

        static void CreateCurrencyRatesMeasureGroup(Cube cube)
        {
            // Create the Currency Rates measure group
            Database db = cube.Parent;
            MeasureGroup mg = cube.MeasureGroups.Add("Currency Rates");
            mg.StorageMode = StorageMode.Molap;
            mg.ProcessingMode = ProcessingMode.LazyAggregations;
            mg.Type = MeasureGroupType.ExchangeRate;

            #region Create measures

            Measure meas;

            meas = mg.Measures.Add("Average Rate");
            meas.AggregateFunction = AggregationFunction.AverageOfChildren;
            meas.FormatString = "#,#.00";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactCurrencyRate", "AverageRate");

            meas = mg.Measures.Add("End of Day Rate");
            meas.AggregateFunction = AggregationFunction.LastNonEmpty;
            meas.FormatString = "#,#.00";
            meas.Source = CreateDataItem(db.DataSourceViews[0], "FactCurrencyRate", "EndOfDayRate");

            #endregion

            #region Create measure group dimensions

            CubeDimension cubeDim;
            RegularMeasureGroupDimension regMgDim;
            MeasureGroupAttribute mgAttr;

            cubeDim = cube.Dimensions.GetByName("Date");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Date").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactCurrencyRate", "TimeKey"));

            cubeDim = cube.Dimensions.GetByName("Source Currency");
            regMgDim = new RegularMeasureGroupDimension(cubeDim.ID);
            mg.Dimensions.Add(regMgDim);
            mgAttr = regMgDim.Attributes.Add(cubeDim.Dimension.Attributes.GetByName("Currency").ID);
            mgAttr.Type = MeasureGroupAttributeType.Granularity;
            mgAttr.KeyColumns.Add(CreateDataItem(db.DataSourceViews[0], "FactCurrencyRate", "CurrencyKey"));

            #endregion

            #region Create partitions

            Partition part;

            part = mg.Partitions.Add("Fact Currency Rate");
            part.StorageMode = StorageMode.Molap;
            part.Source = new TableBinding(db.DataSources[0].ID, "dbo", "FactCurrencyRate");

            #endregion
        }

        static void CreateStoredProcedures(Database db)
        {
            // Create the CLR assembly
            ClrAssembly clrAssembly = db.Assemblies.Add("StoredProcedures");
            clrAssembly.ImpersonationInfo = new ImpersonationInfo(
                ImpersonationMode.ImpersonateServiceAccount);
            clrAssembly.PermissionSet = PermissionSet.Unrestricted;

            // Load the assembly files
            clrAssembly.LoadFiles(Environment.CurrentDirectory
                + @"\StoredProcedures.dll", false);

            clrAssembly.Update();
        }

        static void CreateRolesAndPermissions(Database db)
        {
            Cube cube = db.Cubes[0];
            Role role;
            DatabasePermission dbperm;
            CubePermission cubeperm;

            #region Create the Database Administrators role

            // Create the Database Administrators role.
            role = db.Roles.Add("Database Administrators");
            role.Members.Add(new RoleMember("")); // e.g. redmond\johndoe
            role.Update();

            // Assign administrative permissions to this role.
            // Members of this role can perform any operation within the database.
            dbperm = db.DatabasePermissions.Add(role.ID);
            dbperm.Administer = true;
            dbperm.Update();

            #endregion

            #region Create the Processors role

            // Create the Processors role.
            role = db.Roles.Add("Processors");
            role.Members.Add(new RoleMember("")); // e.g. redmond\johndoe
            role.Update();

            // Assign Read and Process permissions to this role.
            // Members of this role can process objects in the database and query them to verify results.
            // Process permission applies to all contained objects, i.e. all dimensions and cubes.
            // Read permission does not apply to contained objects, so we must assign the permission explicitly on the cubes.
            dbperm = db.DatabasePermissions.Add(role.ID);
            dbperm.Read = ReadAccess.Allowed;
            dbperm.Process = true;
            dbperm.Update();

            cubeperm = cube.CubePermissions.Add(role.ID);
            cubeperm.Read = ReadAccess.Allowed;
            cubeperm.Update();

            #endregion

            #region Create the Writers role

            // Create the Writers role.
            role = db.Roles.Add("Writers");
            role.Members.Add(new RoleMember("")); // e.g. redmond\johndoe
            role.Update();

            // Assign Read and Write permissions to this role.
            // Members of this role can discover, query and writeback to the Adventure Works cube.
            // However cell access and writeback is restricted to the United States (in the Customer dimension).
            dbperm = db.DatabasePermissions.Add(role.ID);
            dbperm.Read = ReadAccess.Allowed;
            dbperm.Update();

            cubeperm = cube.CubePermissions.Add(role.ID);
            cubeperm.Read = ReadAccess.Allowed;
            cubeperm.Write = WriteAccess.Allowed;
            cubeperm.CellPermissions.Add(new CellPermission(CellPermissionAccess.Read, "[Customer].[Country-Region].CurrentMember is [Customer].[Country-Region].[Country-Region].&[United States]"));
            cubeperm.CellPermissions.Add(new CellPermission(CellPermissionAccess.ReadWrite, "[Customer].[Country-Region].CurrentMember is [Customer].[Country-Region].[Country-Region].&[United States]"));
            cubeperm.Update();

            #endregion

            #region Create the Readers role

            // Create the Readers role.
            role = db.Roles.Add("Readers");
            role.Members.Add(new RoleMember("")); // e.g. redmond\johndoe
            role.Update();

            // Assign Read permissions to this role.
            // Members of this role can discover and query the Adventure Works cube.
            // However the Customer dimension is restricted to the United States.
            dbperm = db.DatabasePermissions.Add(role.ID);
            dbperm.Read = ReadAccess.Allowed;
            dbperm.Update();

            cubeperm = cube.CubePermissions.Add(role.ID);
            cubeperm.Read = ReadAccess.Allowed;
            Dimension dim = db.Dimensions.GetByName("Customer");
            DimensionAttribute attr = dim.Attributes.GetByName("Country-Region");
            CubeDimensionPermission cubedimperm = cubeperm.DimensionPermissions.Add(dim.ID);
            cubedimperm.Read = ReadAccess.Allowed;
            AttributePermission attrperm = cubedimperm.AttributePermissions.Add(attr.ID);
            attrperm.AllowedSet = "{[Customer].[Country-Region].[Country-Region].&[United States]}";
            cubeperm.Update();

            #endregion
        }
    }
}
